package rpc.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/*********
 *
 *
 *@author 197
 *@date 2020/6/19 19:11
 *
 **/
public class ReflectionUtils {

  private final static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);

  public static Object newObject(String clsName) {
    return newObject(getClass(clsName));
  }

  public static Object newObject(Class<?> cls) {
    try {
      Constructor<?> cons = cls.getDeclaredConstructor();
      return cons.newInstance();
    } catch (Throwable e) {
      throw new RuntimeException("newObject exception", e);
    }
  }

  public static Class<?> getClass(String s) {
    try {
      return Class.forName(s);
    } catch (Throwable e) {
      throw new RuntimeException("class not find : " + s, e);
    }
  }

  public static int getFliedIntValue(String clazz, String fliedName) {
    try {
      Class<?> aClass = Class.forName(clazz);
      return aClass.getField(fliedName).getInt(aClass);
    } catch (Exception e) {
      logger.error("getFliedIntValue: class:{} ,fliedName {} {}", clazz, fliedName, e.getMessage());
      logger.error("exception:{} stackTrace:{}", e.getMessage(), ExceptionUtils.getTrace(e));
    }
    return 0;
  }

  public static int getFliedIntValue(Class<?> clazz, String fliedName) {
    try {
      return clazz.getField(fliedName).getInt(clazz);
    } catch (Exception e) {
      logger.error("getFliedIntValue: class:{} ,fliedName {} {}", clazz, fliedName, e.getMessage());
      logger.error("exception:{} stackTrace:{}", e.getMessage(), ExceptionUtils.getTrace(e));
    }
    return 0;
  }

  public static Object getFliedValue(Class<?> clazz, String fliedName) {
    try {
      return clazz.getField(fliedName).get(clazz);
    } catch (Exception e) {
      logger.error("exception:{} stackTrace:{}", e.getMessage(), ExceptionUtils.getTrace(e));
    }
    return null;
  }

  public static Object invoke(Method method, Object impl, Object param) {
    try {
      return method.invoke(impl, param);
    } catch (Exception e) {
      logger.error("exception:{} stackTrace:{}", e.getMessage(), ExceptionUtils.getTrace(e));
    }
    return null;
  }

  public static Object populate(Class<?> clazz, Map<String, Object> map) {
    Object o = null;
    try {
      o = clazz.getConstructor().newInstance();
      BeanUtils.populate(o, map);
    } catch (Exception e) {
      logger.error("exception:{} stackTrace:{}", e.getMessage(), ExceptionUtils.getTrace(e));
    }
    return o;
  }
}